package com.pet.pet02.config;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     *定义SpringSecurity密码加密对象
     * @return
     */
    @Bean //对象名默认为方法名
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Autowired
    private AuthenticationSuccessHandler successHandler;
    @Autowired
    private AuthenticationFailureHandler failureHandler;

    /*配置认证管理器（此对象主要负责对客户端输入的用户信息进行认证），在其他配置类中会用到此对象*/
    @Bean
    public AuthenticationManager authenticationManagerBean()
            throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     *在这个方法中定义登录规则
     * 1.对所有请求放行（当前工程只做认证）
     * 2.登录成功信息的返回
     * 3.登录失败信息的返回
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭跨域攻击
        http.csrf().disable();
        //放行所有的请求
        http.authorizeRequests().anyRequest().permitAll();
        //登录成功与失败的处理
        http.formLogin()
                .successHandler(successHandler)
                .failureHandler(failureHandler);
    }
    @Bean
    public AuthenticationSuccessHandler successHandler(){
        return (request,response,authentication) -> {
            //1.构建map对象，封装响应数据
            Map<String,Object> map = new HashMap<>();
            map.put("state",200);
            map.put("message","login ok");
            //2.将map对象写到客户端
            writeJsonToClient(response,map);
        };
    }
    @Bean
    public AuthenticationFailureHandler failureHandler(){
        return (request,response,e) -> {
            //1.构建map对象，封装响应数据
            Map<String,Object> map = new HashMap<>();
            map.put("state",500);
            map.put("message","username or password error");
            //2.将map对象写到客户端
            writeJsonToClient(response,map);
        };
    }
    public void writeJsonToClient(HttpServletResponse response,Object object) throws IOException {
        //2.将对象转换为json
        //Gson --> toJson
        //fastJson --> JSON
        //jackson --> writeValueAsString
        String jsonStr = new ObjectMapper().writeValueAsString(object);
        //3.将json字符串写到客户端
        PrintWriter writer = response.getWriter();
        writer.println(jsonStr);
        writer.flush();
    }
}